<?php

namespace App\Console\Tools\Import;

use Illuminate\Console\Command;
use App\Models\Game\Pay\Order\Wallet as Order;
use App\Models\Elasticsearch\Order\Wallet as EsOrder;

class WalletOrder extends Command
{
    /**
     * 命令名称及签名
     *
     * @var string
     */
    protected $signature = 'tools:import:wallet-order {id?}';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '【工具】导入钱包订单数据到 Elasticsearch';

    /**
     * 创建命令
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * 结束ID
     *
     * @var int
     */
    protected $lastId = 0;

    /**
     * 分页条数
     *
     * @var int
     */
    protected $size = 500;

    /**
     * 批量处理参数
     *
     * @var array
     */
    protected $params;

    /**
     * 执行命令
     *
     * @return mixed
     */
    public function handle()
    {
        $this->lastId = $this->argument('id') ?: $this->lastId;
        // 输出提示【任务时间】
        $this->info($this->description . ': id > ' . $this->lastId);

        // 进度条步数
        $page = ceil(Order::where('id', '>', $this->lastId)->count() / $this->size);

        // 初始化进度条
        $bar = $this->output->createProgressBar($page);
        // 进度条开始
        $bar->start();

        // ES 客户端
        $client = EsOrder::client();

        do {
            // 查询 Mysql 数据
            $collection = Order::orderBy('id')
                ->where('id', '>', $this->lastId)
                ->limit($this->size)
                ->get();

            // 当前分页记录条数
            $count = $collection->count();
            if ($count == 0) {
                break;
            }

            // 初始化参数
            $this->params['body'] = [];
            // 制作批量参数
            $collection->each(function ($item) {
                $this->params['body'][] = [
                    'update' => [
                        '_index' => EsOrder::INDEX_NAME . '-' . date('Y.m.d', $item->created),
                        '_id' => $item->id,
                        // 版本冲突重试次数
                        'retry_on_conflict' => 2,
                    ]
                ];
                $this->params['body'][] = [
                    'doc' => $item->toArray(),
                    // 文档不存在时插入
                    'doc_as_upsert' => true,
                ];
            });

            // 批量插入
            $result = $client->bulk($this->params);
            // 错误判断
            if ($result['errors']) {
                $this->error("\n Elasticsearch 插入数据错误，结束ID：{$this->lastId}");
                foreach ($result['items'] as $item) {
                    if ($item['update']['status'] >= 400) {
                        dd($item);
                    }
                }
            }

            // 记录结束ID
            $this->lastId = $collection->last()->id;

            // 清理数据
            unset($collection, $this->params, $result);
            // 进度条 +1
            $bar->advance();

        } while ($count == $this->size);

        // 进度条结束
        $bar->finish();

        $this->info("\n 数据导入完成，结束ID：{$this->lastId}");
    }
}
